﻿using SqlSugar;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Publicuse.Entity;

namespace Publicuse.Interface
{
    /// <summary>
    /// https://freesql.net/guide/getting-started.html#%E5%AE%89%E8%A3%85%E5%8C%85
    /// </summary>
    public interface IBaseFreeSqlService
    {
        #region 查询 
        /// <summary>
        /// 查询所有的数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="msg"></param>
        /// <returns></returns>
        public List<T> GetAll<T>(out string msg) where T : class, new();

        /// <summary>
        /// 根据SQL查询数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public List<T> QueryBySql<T>(string sql, out string msg) where T : class, new();

        /// <summary>
        /// 根据SQL查询数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public List<T> Query<T>(string sql, out string msg) where T : class, new();

        /// <summary>
        /// 根据SQL查询数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <param name="param"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public List<T> Query<T>(string sql, object parameter, out string msg) where T : class, new();

        /// <summary>
        /// 根据SQL传递参数查询数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <param name="parameter"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public List<T> QueryBySqlPara<T>(string sql, object parameter, out string msg) where T : class, new();

        /// <summary>
        /// 根据条件查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="expression"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public List<T> QueryByExpression<T>(Expression<Func<T, bool>> expression, out string msg) where T : class, new();

        /// <summary>
        /// 通过编号查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public T FindById<T>(int id, out string msg) where T : class, new();

        /// <summary>
        /// 通过编号查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id"></param>
        /// <param name="msg"></param>
        /// <param name="entity"></param>
        public void QueryInfoByID<T>(int id, out string msg, out T entity) where T : class, new();

        /// <summary>
        /// 根据条件查询
        /// </summary>
        /// <param name="expression"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public T FindByExpression<T>(Expression<Func<T, bool>> expression, out string msg) where T : class, new();

        /// <summary>
        /// 根据sql获取数据
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="msg"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public DataTable GetDataTable(string sql, out string msg, object parameters);

        /// <summary>
        /// 根据sql获取数据
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="parameters"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public DataTable GetDataTable(string sql, object parameters, out string msg);


        /// <summary>
        /// 根据sql获取数据
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="msg"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public DataSet GetDataSet(string sql, out string msg, object parameters);

        /// <summary>
        /// 根据sql获取数据
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="parameters"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public DataSet GetDataSet(string sql, object parameters, out string msg);

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="expression"></param>
        /// <param name="orderfile"></param>
        /// <param name="orderByType"></param>
        /// <param name="totalCount"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public List<T> GetPageList<T>(int pageIndex, int pageSize, Expression<Func<T, bool>> expression, Expression<Func<T, object>> orderfile, OrderByType orderByType, out long totalCount, out string msg) where T : class, new();

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="query"></param>
        /// <param name="msg"></param>
        /// <param name="list"></param>
        /// <param name="totalCount"></param>
        public List<T> GetPageListByProc<T>(CommonQuery query, out string msg, out List<T> list, out long totalCount) where T : class, new();

        public List<T> GetPageListBySql<T>(CommonQuery query, out string msg, out List<T> list, out long totalCount) where T : class, new();

        public List<T> GetList<T>(CommonQuery query, out string msg, out List<T> list, out long totalCount) where T : class, new();

        #endregion

        #region 增加 
        /// <summary>
        /// 字典插入
        /// 不能写实体中的属性名，必须和数据库保持一致
        /// </summary>
        /// <param name="keyValuePairs"></param>
        /// <param name="msg"></param>
        /// <param name="aliasname"></param>
        /// <returns></returns>
        public int InsertDictionary(Dictionary<string, object> keyValuePairs, out string msg, string aliasname);

        /// <summary>
        /// 匿名对象插入
        /// </summary>
        /// <param name="ob"></param>
        /// <param name="msg"></param>
        /// <param name="aliasname"></param>
        /// <returns></returns>
        public int InsertAnonyobject(object ob,out string msg, string aliasname);


        /// <summary>
        /// 插入Guid主键自动赋值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public long InsertGuid<T>(T t, out string msg) where T : class, new();

        /// <summary>
        /// 增加实体 
        /// </summary>
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public T InsertBackModel<T>(T t, out string msg) where T : class, new();

        /// <summary>
        /// 增加实体
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public long InserBackId<T>(T t, out string msg) where T : class, new();

        /// <summary>
        /// 增加实体
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public long Insert<T>(T t, out string msg) where T : class, new();

        /// <summary>
        /// 不插入指定字段
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <param name="msg"></param>
        /// <param name="columns"></param>
        /// <returns></returns>
        public long InsertIgnoreColumns<T>(T t,out string msg, params string[] columns) where T : class, new();

        /// <summary>
        /// 不插入指定字段
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <param name="msg"></param>
        /// <param name="columns"></param>
        /// <returns></returns>
        public long InsertIgnoreColumns<T>(T t, out string msg, Expression<Func<T, object>> columns) where T : class, new();

        /// <summary>
        /// 只插入指定字段
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <param name="msg"></param>
        /// <param name="columns"></param>
        /// <returns></returns>
        public long InsertInsertColumns<T>(T t, out string msg, params string[] columns) where T : class, new();

        /// <summary>
        /// 只插入指定字段
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <param name="msg"></param>
        /// <param name="columns"></param>
        /// <returns></returns>
        public long InsertInsertColumns<T>(T t, out string msg, Expression<Func<T, object>> columns) where T : class, new();

        /// <summary>
        //使用参数化内部分页插入
        //优点：500条以下速度最快，兼容所有类型和emoji，10万以上的大数据也能跑，就是慢些，内部分批量处理过了。
        //缺点：500以上就开始慢了，要加事务才能回滚 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public int InsertUseParameter<T>(List<T> t,out string msg) where T : class, new();

        /// <summary>
        /// 大数据写入
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public int InsertBulkCopy<T>(List<T> t,out string msg) where T : class, new();

        /// <summary>
        /// 分页插入
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <param name="pageSize"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public int InsertPage<T>(List<T> t, int pageSize,out string msg) where T : class, new();

        /// <summary>
        /// 批量添加
        /// Z.Dapper.Plus
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public List<T> InsertBatch<T>(List<T> list, out string msg) where T : class, new();

        /// <summary>
        /// 批量添加
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <param name="msg"></param>
        public List<T> Insert<T>(List<T> list, out string msg) where T : class, new();
        #endregion

        #region 修改
        /// <summary>
        /// 根据字典更新
        /// </summary>
        /// <param name="keyValuePairs"></param>
        /// <param name="msg"></param>
        /// <param name="aliasname"></param>
        /// <param name="wherename"></param>
        /// <returns></returns>
        public int UpdateDictionary(Dictionary<string, object> keyValuePairs, out string msg, string aliasname,string wherename);

        /// <summary>
        /// 忽略某一列不更新
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <param name="msg"></param>
        /// <param name="columns"></param>
        /// <returns></returns>
        public int UpdateIgnoreColumns<T>(T t,out string msg, Expression<Func<T, object>> columns) where T : class, new();

        /// <summary>
        /// 只更新某列--按需更新
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <param name="msg"></param>
        /// <param name="columns"></param>
        /// <returns></returns>
        public int UpdateColumns<T>(T t, out string msg, Expression<Func<T, object>> columns) where T : class, new();

        /// <summary>
        /// 更新忽略null并且忽略默认值 (比如int默认值是0就不更新)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <param name="msg"></param>
        /// <param name="ignoreAllNullColumns"></param>
        /// <param name="isOffIdentity"></param>
        /// <param name="ignoreAllDefaultValue"></param>
        /// <returns></returns>
        public int UpdateIgnoreColumns<T>(T t,out string msg, bool ignoreAllNullColumns, bool isOffIdentity = false, bool ignoreAllDefaultValue = false) where T : class, new();

        /// <summary>
        /// 条件更新
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <param name="msg"></param>
        /// <param name="expression"></param>
        /// <returns></returns>
        public int UpdateWhere<T>(T t,out string msg, Expression<Func<T, bool>> expression) where T : class, new();

        /// <summary>
        /// 修改实体
        /// </summary>
        /// <typeparam name="int"></typeparam>
        /// <param name="t"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public int Update<T>(T t, out string msg) where T : class, new();

        /// <summary>
        /// 批量修改
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public int UpdateBatch<T>(List<T> list, out string msg) where T : class, new();

        #endregion

        #region 删除
        /// <summary>
        /// 根据字典集合删除
        /// </summary>
        /// <param name="columns"></param>
        /// <param name="msg"></param>
        /// <param name="aliasname"></param>
        /// <returns></returns>
        public bool DeleteDictionary(List<Dictionary<string, object>> columns, out string msg, string aliasname);

        /// <summary>
        /// 删除指定主键集合数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="msg"></param>
        /// <param name="ids"></param>
        /// <returns></returns>
        public bool Delete<T>(out string msg, long[] ids) where T : BaseModel<long>, new();

        /// <summary>
        /// 根据ID删除
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public bool Delete<T>(int id, out string msg) where T : BaseModel<long>, new();

        /// <summary>
        /// 根据条件删除
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="where"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public bool Delete<T>(Expression<Func<T, bool>> where, out string msg) where T : class, new();

        /// <summary>
        /// 根据集合删除
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public bool Delete<T>(List<T> t, out string msg) where T : BaseModel<long>, new();

        /// <summary>
        /// 根据条件删除
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dywhere"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public bool Delete<T>(object dywhere, out string msg) where T : BaseModel<long>, new();

        #endregion

        #region 执行SQL
        /// <summary>
        /// 执行SQL
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="msg"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public bool ExecuteSql(string sql, out string msg, object parameters);

        /// <summary>
        /// 执行SQL
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="parameters"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public bool ExecuteSql(string sql, object parameters, out string msg);

        #endregion

        #region 外部执行具体操作
        /// <summary>
        /// 外部执行具体操作
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="action"></param>
        /// <param name="istran"></param>
        public void Work(out string msg, Action<IFreeSql> action, bool istran = false);
        #endregion

    }
}
